<template>
    <div class="about">
        <a-button style="float:right" type="primary">返回</a-button>
        <h1>
            变量提升
        </h1>

        <a-card title="提升结合编译原理，理解更为透彻">
            <a slot="extra">示例代码node环境运行</a>
            <div class="left" style="float:left">
                <a-card title="单选">
                    <code-box :width="30">
                        <pre>
                        (function(){
                            var x=foo();
                            var foo=function foo(){
                                return 'foobar';
                            }
                            return x;
                        })();
                    </pre
                        >
                    </code-box>
                    <ul>
                        <li>A foo()</li>
                        <li>B 类型错误</li>
                        <li>C undefined</li>
                        <li>D foobar</li>
                    </ul>
                    <a-card-meta title="答案" description="B"></a-card-meta>
                    <strong
                        >①函数声明和变量声明都会被提升，
                        但是函数会首先被提升,然后才是变量；
                        ②函数声明会被提升,但是函数表达式却不会被提升
                    </strong>
                </a-card>
            </div>
            <div class="right" style="float:right">
                <h3>代码解析：</h3>
                <code-box>
                    <pre>
(function(){
    var foo;
    var x=foo();   // 此时foo为undefined，抛出TypeError
    var foo=function foo(){
        return 'foobar';
    }
    return x;
})();
                    </pre>
                </code-box>
                <textarea cols="60" rows="10">
     这段程序中的变量标识符 foo() 被提升并分配给所在作用域(在这里是全局作用域),因此 foo() 不会导致 ReferenceError 。
     但是 foo 此时并没有赋值(如果它是一个函数声明而不 是函数表达式,那么就会赋值)。
      foo() 由于对 undefined 值进行函数调用而导致非法操作, 因此抛出 TypeError 异常。 </textarea
                >
            </div>
        </a-card>
        <br />
        <a-card-meta
            title="总结"
            description="
            无论作用域中的声明出现在什么地方,都将在代码本身被执行前首先进行处理。
            可以将这个过程形象地想象成所有的声明(变量和函数)都会被“移动”到各自作用域的
            最顶端,这个过程被称为提升。 "
        >
        </a-card-meta>
        <br />
        <hr />
        <a-card-meta
            title="参考:"
            description="你不知道的JavaScript（上卷）第四章 提升 ，4.3函数有限"
        ></a-card-meta>
    </div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
import CodeBox from '@/components/CodeBox.vue';
@Component({
    components: {
        CodeBox,
    },
})
export default class VariableLifting extends Vue {
    private result: any;
}
</script>
<style lang="less" scoped>
.left {
    display: flex;
    flex-direction: column;
    width: 50%;
    strong {
        em {
            font-size: 1.2rem;
            color: goldenrod;
        }
    }
}
.right {
    position: relative;
    padding-left: 1rem;
    letter-spacing: 0.15rem;
    width: 50%;
    :before {
        content: '';
        display: inline-block;
        width: 5px;
        height: 100%;
        background: #54b689;
        position: absolute;
        left: 0;
        top: 0;
    }
    textarea {
        display: flex;
        flex-direction: column;
        font-size: 1.1rem;
        color: #54b689;
    }
}
</style>
